function [ZeroRates, CurveDates] = disc2zero(DiscRates, CurveDates, Settle,...
    Compounding, Basis)
%DISC2ZERO Zero curve given a discount curve.
%   Given a discount curve and a set of maturity dates, DISC2ZERO generates a
%   zero curve for the investment horizon represented by the maturity dates;
%   zero rates are the yields to maturity on theoretical zero coupon bonds.
%
%   [ZeroRates, CurveDates] = disc2zero(DiscRates, CurveDates, Settle, ...
%        Compounding, Basis)
%
%   Inputs:
%   DiscRates   - (required) An Nx1 vector of discount factors in decimal form
%                 which in aggregate represent a discount curve for a given
%                 investment horizon.
%
%   CurveDates  - (required) An Nx1 vector of maturity dates in serial date
%                 number form which correspond to the discount factors.
%
%   Settle      - (required) Scalar value in serial date number form
%                 representing the settlement date for the discount factor.
%
%   Compounding - (optional) Scalar value representing the rate at which the
%                 output zero rates are compounded when annualized.
%                 Possible values include:
%                   1 - annual compounding
%                   2 - semi-annual compounding (default)
%                   3 - compounding three times per year
%                   4 - quarterly compounding
%                   6 - bi-monthly compounding
%                  12 - monthly compounding
%                 365 - daily compounding
%                  -1 - continuous compounding
%
%   Basis       - (optional) Scalar value representing the basis to be used in
%                 annualizing the output zero rates.
%                 Possible values include:
%                 0 - actual/actual (default)
%                 1 - 30/360 SIA
%                 2 - actual/360
%                 3 - actual/365
%                 4 - 30/360 PSA
%                 5 - 30/360 ISDA
%                 6 - 30/360 European
%                 7 - actual/365 Japanese
%                 8 - actual/actual ISMA
%                 9 - actual/360 ISMA
%                10 - actual/365 ISMA
%                11 - 30/360 ISMA
%                12 - actual/365 ISDA
%                13 - bus/252
%
%   Outputs:
%   ZeroRates  - An Nx1 column vector of zero rates in decimal form.
%   CurveDates - An Nx1 column vector of maturity dates in serial date number
%                form representing the maturity date for each zero rate
%                contained in ZeroRates.
%
%   See also ZERO2DISC, ZBTPRICE, ZBTYIELD, TERMFIT, ZERO2FWD, FWD2ZERO,
%            PYLD2ZERO, ZERO2PYLD.

%   Copyright 1995-2009 The MathWorks, Inc.
%   $Revision: 1.14.2.13 $   $Date: 1997/08/12 08:43:00


%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%
%                   ************* GET/PARSE INPUT(S) **************
%
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

if (nargin < 3)
    error('finance:disc2zero:notEnoughInputs', ...
        'Too few inputs.');
end


% Check the number of arguments passed in and set defaults
if (nargin < 5)
    Basis = 0;
end

if (nargin < 4)
    Compounding = 2;
end


% Parse output compounding argument
if (length(Compounding(:)) > 1)
    error('finance:disc2zero:invalidCompoundingSize',...
        'Output compounding must be a scalar value.');
end

if all(Compounding ~= [-1 1 2 3 4 6 12 365])
    error('finance:disc2zero:invalidCompounding',...
        'Invalid output compounding specified.');
end

% Parse output basis argument
if (length(Basis(:)) > 1)
    error('finance:disc2zero:invalidBasisSize',...
        'Output basis must be a scalar value.');
end

if any(~isvalidbasis(Basis))
    error('finance:disc2zero:invalidBasis',...
        'Invalid output bond basis specified.');
end

% Settle must be > maturity
if any(CurveDates <= Settle)
    error('Finance:disc2zero:invalidSettle', ...
        'Settle must precede all dates in CurveDates.')
end

% Set continuous output compounding flag
OutContCompFlag = 0;
if (Compounding == -1)
    OutContCompFlag = 1;
end

% Sort the rates with respect to the curve dates
[Temp, SortIndex] = sort(CurveDates); %#ok
DiscRates = DiscRates(SortIndex);

% Get the maturity values for T in fractions of a year
OutYearMats = yearfrac(Settle, CurveDates, Basis);

% Check compounding flag and convert zero rates to discount factor
if (OutContCompFlag)
    % Continuous compounding
    ZeroRates = -log(DiscRates) ./ OutYearMats;
else
    % Discrete compounding
    ZeroRates = (DiscRates .^ (-1 ./ (OutYearMats .* Compounding)) - 1)...
        .* Compounding;
end